package Redis.StringRedisTemplate.utils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;


@Component
public class RedisOperator {

	@Autowired
	private StringRedisTemplate redisTemplate;
	
	// Key（键），简单的key-value操作

	/**
	 * 实现命令：TTL key，以秒为单位，返回给定 key的剩余生存时间(TTL, time to live)。
	 * 
	 * @param key
	 * @return
	 */
	public long ttl(String key) {
		return redisTemplate.getExpire(key);
	}
	
	/**
	 * 实现命令：expire 设置过期时间，单位秒
	 * 
	 * @param key
	 * @return
	 */
	public void expire(String key, long timeout) {
		redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
	}
	
	/**
	 * 实现命令：INCR key，增加key一次
	 * 
	 * @param key
	 * @return
	 */
	public long incr(String key, long delta) {
		return redisTemplate.opsForValue().increment(key, delta);
	}

	/**
	 * 实现命令：KEYS pattern，查找所有符合给定模式 pattern的 key
	 */
	public Set<String> keys(String pattern) {
		return redisTemplate.keys(pattern);
	}

	/**
	 * 实现命令：DEL key，删除一个key
	 * 
	 * @param key
	 */
	public void del(String key) {
		redisTemplate.delete(key);
	}

	// String（字符串）

	/**
	 * 实现命令：SET key value，设置一个key-value（将字符串值 value关联到 key）
	 * 
	 * @param key
	 * @param value
	 */
	public void set(String key, String value) {
		redisTemplate.opsForValue().set(key, value);
	}

	/**
	 * 实现命令：SET key value EX seconds，设置key-value和超时时间（秒）
	 * 
	 * @param key
	 * @param value
	 * @param timeout
	 *            （以秒为单位）
	 */
	public void set(String key, String value, long timeout) {
		redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
	}

	/**
	 * 实现命令：GET key，返回 key所关联的字符串值。
	 * 
	 * @param key
	 * @return value
	 */
	public String get(String key) {
		return (String)redisTemplate.opsForValue().get(key);
	}

	// Hash（哈希表）

	/**
	 * 实现命令：HSET key field value，将哈希表 key中的域 field的值设为 value
	 * 
	 * @param key
	 * @param field
	 * @param value
	 */
	public void hset(String key, String field, Object value) {
		redisTemplate.opsForHash().put(key, field, value);
	}

	/**
	 * 实现命令：HGET key field，返回哈希表 key中给定域 field的值
	 * 
	 * @param key
	 * @param field
	 * @return
	 */
	public String hget(String key, String field) {
		return (String) redisTemplate.opsForHash().get(key, field);
	}

	/**
	 * 实现命令：HDEL key field [field ...]，删除哈希表 key 中的一个或多个指定域，不存在的域将被忽略。
	 * 
	 * @param key
	 * @param fields
	 */
	public void hdel(String key, Object... fields) {
		redisTemplate.opsForHash().delete(key, fields);
	}

	/**
	 * 实现命令：HGETALL key，返回哈希表 key中，所有的域和值。
	 * 
	 * @param key
	 * @return
	 */
	public Map<Object, Object> hgetall(String key) {
		return redisTemplate.opsForHash().entries(key);
	}

	// List（列表）

	/**
	 * 实现命令：LPUSH key value，将一个值 value插入到列表 key的表头
	 * 
	 * @param key
	 * @param value
	 * @return 执行 LPUSH命令后，列表的长度。
	 */
	public long lpush(String key, String value) {
		return redisTemplate.opsForList().leftPush(key, value);
	}

	/**
	 * 实现命令：LPOP key，移除并返回列表 key的头元素。
	 * 
	 * @param key
	 * @return 列表key的头元素。
	 */
	public String lpop(String key) {
		return (String)redisTemplate.opsForList().leftPop(key);
	}
	
	/**
	 * 实现命令：llen key，返回列表 key的长度。
	 * 
	 * @param key
	 * @return 列表key的头元素。
	 */
	public long llen(String key) {
		return redisTemplate.opsForList().size(key);
	}

	/**
	 * 实现命令：RPUSH key value，将一个值 value插入到列表 key的表尾(最右边)。
	 * 
	 * @param key
	 * @param value
	 * @return 执行 LPUSH命令后，列表的长度。
	 */
	public long rpush(String key, String value) {
		return redisTemplate.opsForList().rightPush(key, value);
	}
	
	/**
	 * StringRedisTemplate其他命令的测试。
	 * 
	 * @param key
	 * @param value
	 * @return 
	 */
	public void testStringRedisTemplate() {
		
		// SetOperations操作集合Set 
		 SetOperations<String, String> set = redisTemplate.opsForSet();
		 set.add("set1","22");
		 set.add("set1","33");
		 set.add("set1","44");
		 Set<String> resultSet =redisTemplate.opsForSet().members("set1");
		 redisTemplate.opsForSet().add("set2", "1","2","3");//向指定key中存放set集合
		 Set<String> resultSet1 =redisTemplate.opsForSet().members("set2");
		 System.out.println("resultSet:"+resultSet);
		 System.out.println("resultSet1:"+resultSet1);

		//获取ListOperations操作List数据，list可以用来实现队列。
		 //将数据添加到key对应的现有数据的左边
		 Long redisList = redisTemplate.opsForList().leftPush("redisList", "3");
		 redisTemplate.opsForList().leftPush("redisList", "4");
		 //将数据添加到key对应的现有数据的右边
		 Long size = redisTemplate.opsForList().size("redisList");
		 //从左往右遍历
		 String leftPop = redisTemplate.opsForList().leftPop("redisList");
		 //从右往左遍历
		 String rightPop = redisTemplate.opsForList().rightPop("redisList");
		 //查询全部元素
		 List<String> range = redisTemplate.opsForList().range("redisList", 0, -1);
		 //查询前三个元素
		 List<String> range1 = redisTemplate.opsForList().range("redisList", 0, 3);
		 //从左往右删除list中元素A  (1:从左往右 -1:从右往左 0:删除全部)
		 Long remove = redisTemplate.opsForList().remove("key", 1, "A");
		 System.out.println("redisList----"+redisList);
		 System.out.println("size----"+size);
		 System.out.println("leftPop----"+leftPop);
		 System.out.println("rightPop----"+rightPop);
		 System.out.println("range----"+range);
		 System.out.println("range1----"+range1);
		 System.out.println("remove----"+remove);  

		//判断key对应的map中是否存在hash
		Boolean aBoolean = redisTemplate.opsForHash().hasKey("hash", "hash1");
		//往key对应的map中新增(key1,value1)
		redisTemplate.opsForHash().put("hash", "hash1", "value1");
		//获取key对应的map中hash1的值
		Object o = redisTemplate.opsForHash().get("hash", "hash1");
		//删除key对应的map中多个子hash(可变参数)
		Long delete = redisTemplate.opsForHash().delete("hash", "key1", "key2", "key3");
		//获取hash对应的map
		Map<Object, Object> hash = redisTemplate.opsForHash().entries("hash");
		//获取hash对应的map中全部子hash集合
		Set<Object> hash1 = redisTemplate.opsForHash().keys("hash");
		//获取hash对应的map中全部value集合
		List<Object> hash2 = redisTemplate.opsForHash().values("hash");

		//删除key
		Boolean key = redisTemplate.delete("key");  
		//key 自增1
		Long count = redisTemplate.boundValueOps("count").increment(1);//val +1 
		//获取过期时间，如果key没有过期时间则为-1
		Long time = redisTemplate.getExpire("count"); 
		
	}
	

}